#include <gl/glut.h>
#include <math.h>
#include <stdarg.h>

#define MYLIB_POINT_MASS 0x1
#define MYLIB_TWO_POINT_MASS 0x2
#define MYLIB_ROD 0x3
#define MYLIB_CIRCULAR_HOOP 0x4
#define MYLIB_SOLID_DISK 0x5
#define MYLIB_CYLINDRICAL_SHELL 0x6
#define MYLIB_CYLINDRICAL_SOLID 0x7
#define MYLIB_CYLINDRICAL_TUBE 0x8
#define MYLIB_TETRAHEDRON 0x9
#define MYLIB_OCTAHEDRON_HOLLOW 0x10
#define MYLIB_OCTAHEDRON_SOLID 0x11
#define MYLIB_SPHERE_HOLLOW 0x12
#define MYLIB_SPHERE_SOLID 0x13
#define MYLIB_SPHERE_SHELL 0x14
#define MYLIB_CONE 0x15
#define MYLIB_TORUS 0x16
#define MYLIB_ELLIPSOID 0x17
#define MYLIB_PLATE 0x18
#define MYLIB_SOLID_CUBOID 0x19

// Moment of Inertia

class MOI
{
	int object_type;
	double I;
	double point_mass(double m, double x, double y)
	{
		return m*(x*x + y*y);
	}
	double two_point_mass(double m1, double m2, double x)
	{
		return ((m1*m2) / (m1 + m2))*(x*x);
	}
	double rod(double mass,double length)
	{
		return (mass*length*length) / 12.0;
	}
	double circular_hoop(double mass, double radius)
	{
		return (mass * radius * radius);
	}
	double solid_disk(double mass, double radius)
	{
		return (mass * radius * radius) / 2.0;
	}
	double cylindrical_shell(double mass,double radius)
	{
		return (mass * radius * radius);
	}
	double cylindrical_solid(double mass, double radius, double height,char axis)
	{
		if (axis == 'z')
			return (mass * radius * radius) / 2.0;
		else if (axis == 'x' || axis == 'y')
			return ((1.0 / 12.0)*mass)*(3.0 * radius*radius + height*height);
		else 
			return 0;
	}
	double cylindrical_tube(double mass, double radius1,double radius2, double height, double axis)
	{
		if (axis == 'z')
			return 0.5*mass*(radius1*radius1 + radius2*radius2);
		else
			return (1.0 / 12.0)*mass*(3 * (radius1*radius1 + radius2*radius2) + height*height);
	}
public:
	MOI()
	{
		I = 0;
	}
	MOI(int n,...)
	{
		va_list l;
		va_start(l, n);
		object_type = va_arg(l,int);
		if (object_type == MYLIB_POINT_MASS)
		{
			double mass, x,y;
			mass = va_arg(l,double);
			x = va_arg(l,double);
			y = va_arg(l, double);
			I = point_mass(mass, x, y);
		}
		else if (object_type == MYLIB_TWO_POINT_MASS)
		{
			double m1, m2, x;
			m1 = va_arg(l, double);
			m2 = va_arg(l, double);
			x = va_arg(l, double);
			I = two_point_mass(m1,m2,x);
		}
		else if (object_type == MYLIB_ROD)
		{
			double mass, length;
			mass = va_arg(l, double);
			length = va_arg(l, double);
			I = rod(mass,length);
		}
		else if (object_type == MYLIB_CIRCULAR_HOOP)
		{
			double mass, radius;
			mass = va_arg(l, double);
			radius = va_arg(l, double);
			I = circular_hoop(mass, radius);
		}
		else if (object_type == MYLIB_SOLID_DISK)
		{
			double mass, radius;
			mass = va_arg(l, double);
			radius = va_arg(l, double);
			I = solid_disk(mass,radius);
		}
		else if (object_type == MYLIB_CYLINDRICAL_SHELL)
		{
			double mass, radius;
			mass = va_arg(l, double);
			radius = va_arg(l, double);
			I = cylindrical_shell(mass, radius);
		}
		else if (object_type == MYLIB_CYLINDRICAL_SOLID)
		{
			double mass, radius, height;
			char axis;
			mass = va_arg(l, double);
			radius = va_arg(l, double);
			height = va_arg(l,double);
			axis = va_arg(l,char);
			I = cylindrical_solid(mass, radius, height, axis);
		}
		else if (object_type == MYLIB_CYLINDRICAL_TUBE)
		{
			double mass, radius1, radius2, height, axis;
			mass = va_arg(l, double);
			radius1 = va_arg(l, double);
			radius2 = va_arg(l, double);
			height = va_arg(l, double);
			axis = va_arg(l, double);
			I = cylindrical_tube(mass, radius1, radius2, height, axis);
		}
		va_end(l);
	}
};